# -*- coding: utf-8 -*-
# author:Eduardo Cardeira
# date: 21/10/2013
# obs.: Aula 5 - Exercicios de Programação Orientada a Objectos

###### Declaração de Classe #####

class Cartao:
    """
        uma classe que representa o conceito de cartao
    """

    entidade = "" # uma variavel da classe

    def __init__(self, numero = 0):
        """construtor"""
        self.numero = numero # uma variavel de instancia

    def __str__ (self):
        """resultado da impressao de um objeto"""
        return "numero {0}".format(self.numero)
#instancias da classe
obj1 = Cartao(123456789)
obj2 = Cartao(7843972)
Cartao.entidade = "Governo"
print obj1, obj1.entidade
print obj2, obj2.entidade

##### Uso de Métodos #####

# funcao definida fora da classe: mau codigo

def f1(self, x, y):
    return min(x, y)
class C:
    f = f1
obj = C()
print obj.f(2, 4)

class Saco:
    def __init__(self):
        self.data = []
    def add(self, x):
        self.data.append(x)
    def add2(self, x):
        self.add(x)
        self.add(x)
obj = Saco()
obj.add2("arroz ")
print obj.data

##### Informação Adicional #####

# alguma informacao sobre as classes

class Fruta:
    """ documentacao da classe Fruta """
    def __init__(self, tipo):
        """ inicializa com tipo de Fruta """
        self.tipo = tipo
    def citrino(self, citrus = False):
        """ por defeito __citrus == False """
        self.__citrus = citrus
print Fruta.__doc__
obj = Fruta("pessego")
print obj.__class__

##### Herança Múltipla #####

class MeioTransporte:
    def __init__(self, combustivel = "gasolina"):
        self.combustivel = combustivel
    def __str__(self): return " combustivel = " + str(self.combustivel)

class Rodas:
    def __init__(self, numero_rodas = 4):
        self.numero_rodas = numero_rodas
    def __str__(self):
        return " numero rodas = " + str(self.numero_rodas)

class Carro(MeioTransporte, Rodas):
    def __init__(self, combustivel, numero_rodas):
        MeioTransporte.__init__(self, combustivel)
        Rodas.__init__(self, numero_rodas)
    def __str__(self):
        return MeioTransporte.__str__(self) + Rodas.__str__(self)
obj = Carro("gasoleo", 6)
print obj

##### Variáveis Privadas e Verificação de Tipos #####

class MeioTransporte:
    def __init__(self, combustivel = "gasolina"):
        self.combustivel = combustivel
        self.__privado = True
    def __str__(self):
        return " combustivel = " + str(self.combustivel)

class Carro(MeioTransporte):
    def __init__(self, combustivel):
        MeioTransporte.__init__(self, combustivel)
    def __str__(self):
        return MeioTransporte.__str__(self)

obj = Carro("gasoleo")
print isinstance(obj, MeioTransporte)
print issubclass(Carro, MeioTransporte)
try:
    print obj.__privado
except AttributeError:
    print "--privado e uma variavel privada"

##### Classes Derivadas de Novo Estilo #####

class Cartao(object):
    def __init__(self, nome):
        self.nome = nome
    def __str__(self):
        return str(self.nome)

class CartaoCidadao(Cartao):
    def __init__(self, nome, numero):
        self.numero = numero
        super(CartaoCidadao, self).__init__(nome)

class ListaCidadao(list):
    def __str__(self):
        s = ""; c = 0
        for x in self:
            c += 1; s += "\n" + str(c) + "   " + str(x)
        return s

obj = CartaoCidadao("Eleuterio Coelho", "12345")
print obj.nome
lista1 = ListaCidadao()
lista1.append(Cartao("Ildefonso Coelho"))
lista1.append(Cartao("Hermenegildo Coelho"))
print lista1

#####Exceções #####

class UserClass:
    pass

try:
    raise(UserClass)
except UserClass:
    print "arggghhh..."

